package com.rdtravel.valueobjects;

import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;

import javax.persistence.Embeddable;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.AssertTrue;
import javax.validation.constraints.NotNull;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;

import org.springframework.format.annotation.DateTimeFormat;

@Embeddable
@XmlAccessorType(XmlAccessType.FIELD)
public class Period implements Serializable {
	private static final long serialVersionUID = 1L;
	@Temporal(TemporalType.DATE)
	@NotNull
	@DateTimeFormat(style = "S-")
	private Date departureDate;
	@Temporal(TemporalType.DATE)
	@NotNull
	@DateTimeFormat(style = "S-")
	private Date returnDate;

	public int getNumberOfDays() {
		Calendar calendar = Calendar.getInstance();
		int numberOfDays = 0;
		calendar.setTime(departureDate);
		while (calendar.getTime().compareTo(returnDate) <= 0) {
			numberOfDays++;
			calendar.add(Calendar.DAY_OF_YEAR, 1);
		}
		return numberOfDays;
	}

	@AssertTrue(message = "{returnDateShouldComeOnOrAferDepartureDate}")
	public boolean isRetunrDateOnOrAfterDepartureDate() {
		if (departureDate == null || returnDate == null) {
			return true;
		}
		return  returnDate.compareTo(departureDate) >= 0;
	}

	public Date getDepartureDate() {
		return departureDate == null ? departureDate : (Date) departureDate
				.clone();
	}

	public void setDepartureDate(Date departureDate) {
		this.departureDate = departureDate == null ? null
				: (Date) departureDate.clone();

	}

	public Date getReturnDate() {
		return returnDate == null ? returnDate : (Date) returnDate.clone();
	}

	public void setReturnDate(Date returnDate) {
		this.returnDate = returnDate == null ? null : (Date) returnDate.clone();

	}

	@Override
	public String toString() {
		return "Period [departureDate=" + departureDate + ", returnDate="
				+ returnDate + "]";
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((departureDate == null) ? 0 : departureDate.hashCode());
		result = prime * result
				+ ((returnDate == null) ? 0 : returnDate.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (!(obj instanceof Period)) {
			return false;
		}
		Period other = (Period) obj;
		if (departureDate == null) {
			if (other.departureDate != null) {
				return false;
			}
		} else if (!departureDate.equals(other.departureDate)) {
			return false;
		}
		if (returnDate == null) {
			if (other.returnDate != null) {
				return false;
			}
		} else if (!returnDate.equals(other.returnDate)) {
			return false;
		}
		return true;
	}

}
